#!/usr/local/bin/python3
# -*- coding: utf-8 -*-

"""
@File    : exp_cross_data.py
@Author  : different && 道阻且长,行则将至 行而不辍,未来可期
@Time    : 2021/10/19 15:11
@Desc    :

"""
import ast

from natsort import natsorted

from apps.models.charts import DataSourceContent
from apps.models.cross_group import CrossAttr, CrossAttrGroup
from expand.exp_data.exp_base_data import BaseData
from expand.exp_data.tools.data_format import group_data_format, is_number


def param_add(param: dict, res, name=None):
    """字典组合"""
    if name:
        param[name + '_listing数'] = res[0]['count']
        param[name + '_总月销量'] = res[0]['sum']
        param[name + '_总销量占比'] = res[0]['percentage']
        param[name + '_平均销量'] = res[0]['avg']
    else:
        param['total_listing数'] = res[0]['count']
        param['total_总月销量'] = res[0]['sum']
        param['total_总销量占比'] = res[0]['percentage']
        param['total_平均销量'] = res[0]['avg']
    return param


class CrossData(BaseData):
    """
        交叉表
    """

    def __init__(self, pk) -> None:
        super().__init__(pk)
        # 主属性
        self.attr_titles = self.cross_attr_title()
        self.main_attr = self.attr_titles.pop(0)
        self.other_attrs = self.attr_titles

    def cross_attr_title(self):
        """返回一个列表，列表[0] 为主属性"""
        attr = DataSourceContent.query.filter_by(table_id=self.pk).limit(1).first()
        if len(attr_data := list(ast.literal_eval(attr.attr))):
            return attr_data
        raise '主属性为空'

    def cross_attr_group(self):
        attrs = {}
        other_attr = {}
        # 首先查询属性表是否有数据
        # 属性表有数据的情况下

        # 如果属性表不为空并且有主属性
        if CrossAttr.query.filter_by(table_id=self.pk, is_main_attr=True).all():
            query_attrs = CrossAttr.query.filter_by(table_id=self.pk).all()
            for attr in query_attrs:
                _arr = []
                attr_group = CrossAttrGroup.query.filter_by(cross_attr_id=attr.id).all()
                for bound in attr_group:
                    if bound.lower_bound == bound.upper_bound:
                        _arr.append(str(bound.lower_bound))
                    else:
                        _arr.append(str(bound.lower_bound + '-' + bound.upper_bound))
                if is_number(_arr[0]):
                    _arr = natsorted(_arr)
                # 主属性逻辑
                if attr.is_main_attr:
                    attrs['main_attr'] = {attr.attr_name: _arr}
                else:
                    # 非主属性逻辑
                    other_attr[attr.attr_name] = _arr
            attrs['other_attr'] = other_attr
            return attrs
        """交叉表默认分组数据"""
        goods_all_attr = DataSourceContent.query.filter_by(table_id=self.pk).with_entities(DataSourceContent.attr).all()
        if len(attr_name := self.cross_attr_title()) == len(
                attr_data := list(zip(*[ast.literal_eval(line[0]).values() for line in goods_all_attr]))):
            for x, y in zip(attr_name, attr_data):
                y = natsorted([str(j) for j in set(y)])
                if x == self.cross_attr_title()[0]:
                    attrs['main_attr'] = {x: y}
                else:
                    other_attr[x] = y
            attrs['other_attr'] = other_attr
        return attrs

    def cross_table_title(self):
        level_1 = []
        level_2 = []
        level_3 = []
        data = self.cross_attr_group()
        level_1.append(
            {'title': '主属性', 'field': 'main_attr', 'align': "center", 'fixed': "left",
             'rowspan': 3,
             'width': 120})
        level_1.append(
            {'title': '图片', 'field': 'image_url', "templet": "#showImg", 'align': "center", 'fixed': "left",
             'rowspan': 3, 'width': 120})
        level_1.append({'title': '总计', 'field': '总计', 'align': "center", 'rowspan': 2, 'colspan': 4})
        level_3.append({'title': 'listing数', 'field': 'total_listing数', 'align': "center"})
        level_3.append({'title': '总月销量', 'field': 'total_总月销量', 'align': "center"})
        level_3.append({'title': '总销量占比', 'field': 'total_总销量占比', 'align': "center"})
        level_3.append({'title': '平均销量', 'field': 'total_平均销量', 'align': "center"})
        for k, v in data['other_attr'].items():
            k = str(k)
            level_1.append({'title': k, 'filter': k, 'align': 'center', 'rowspan': 1, 'colspan': 4 * len(v)})
            for sub_attr in v:
                sub_attr = str(sub_attr)
                level_2.append({'title': sub_attr, 'align': "center", 'colspan': 4, 'rowspan': 1})
                level_3.append({'title': 'listing数', 'field': k + sub_attr + '_listing数', 'align': "center"})
                level_3.append({'title': '总月销量', 'field': k + sub_attr + '_总月销量', 'align': "center"})
                level_3.append({'title': '总销量占比', 'field': k + sub_attr + '_总销量占比', 'align': "center"})
                level_3.append({'title': '平均销量', 'field': k + sub_attr + '_平均销量', 'align': "center"})
        return level_1, level_2, level_3

    def cross_table_data(self):
        # 获取主属性
        other_param = {}
        result = []
        image_url = None
        data = self.cross_attr_group()
        main_attr_name, = data['main_attr']
        for main_groups in data['main_attr'][main_attr_name]:

            param = {}

            if '&' in main_groups:
                groups = main_groups.split('&')
                main_req = {main_attr_name: groups}
                main_attr = main_groups
                is_main_multi = True
            else:
                # 主属性区间最大值和最小值
                min_main_group, max_main_group = group_data_format(main_groups)
                # 获取图片地址
                main_req = {main_attr_name: [min_main_group, max_main_group]}
                main_attr = group_data_format([min_main_group, max_main_group], status=True)
                is_main_multi = False

            image_url = self.conn.execute(self.group_image(main_req)).first()[0]
            param['image_url'] = image_url

            # 主属性区间合并
            param['main_attr'] = main_attr

            # 总计属性
            main_total_res = [dict(zip(i.keys(), i)) for i in
                              self.conn.execute(self.total_sql(main_req, is_main_multi=is_main_multi))]
            param = param_add(param=param, res=main_total_res)
            # 次属性组合 查询
            for other_attr_name, other_attr_groups in data['other_attr'].items():
                for other_group in other_attr_groups:
                    if '&' in other_group:
                        multi_group = other_group.split('&')
                        other_req = {
                            main_attr_name: main_req[main_attr_name],
                            other_attr_name: multi_group
                        }
                        group_title = other_group
                        is_multi = True
                    else:
                        min_other_group, max_other_group = group_data_format(other_group)
                        other_req = {
                            main_attr_name: main_req[main_attr_name],
                            other_attr_name: [min_other_group, max_other_group]
                        }
                        group_title = group_data_format([min_other_group, max_other_group], status=True)
                        is_multi = False

                    other_res = [dict(zip(i.keys(), i)) for i in
                                 self.conn.execute(
                                     self.cross_data_sql(other_req, is_multi=is_multi, is_main_multi=is_main_multi))]
                    name = other_attr_name + group_title
                    param = param_add(param, other_res, name)

                    # 次属性总计
                    other_total_req = {other_attr_name: other_req[other_attr_name]}
                    other_total_res = [dict(zip(i.keys(), i)) for i in
                                       self.conn.execute(self.total_sql(other_total_req, is_main_multi=is_multi))]
                    other_param = param_add(other_param, other_total_res, name)
            result.append(param)
        # 次属性总计
        other_param['main_attr'] = '总计'
        other_param['image_url'] = image_url
        all_total = [dict(zip(i.keys(), i)) for i in self.conn.execute(self.all_total_sql())]
        other_param = param_add(other_param, all_total)
        result.append(other_param)
        return result
